
#ifndef _TTG_SERVICES_SERVICEBASE_
#define _TTG_SERVICES_SERVICEBASE_
#include "Common/Definitions.h"

#include <vector>
#include <Common/Structures.h>

#include "SettingsKeeper/SettingsKeeper.h"
#include "Logger/Logger.h"
#include "PublisherBase/Publishers.h"
#include "PublisherBase/PublisherBase.h"
#include "DllLoader/DllLoader.h"
#include "Timer/Timer.h"
#include "DeviceAnalyzer/DeviceAnalyzer.h"
#include "TaskScheduler/TaskScheduler.h"

namespace ttg
{
	namespace services
	{
		class ServiceBase
		{
			private:
				static ServiceBase *ref;
			private:
				structures::Dictionary<Service> *objects;		//all objects.
				std::vector<Service *> updatables;				//objects, that are really updatable.
				ttg::structures::Loopback<bool> on_start;		//actions, that should be performed
																//after initialization.
				ttg::structures::Loopback<bool> on_stop;		//actions, that should be performed
																//before closing.
			private:
				//Finds object with given name and starts it and dependent objects.
				Service *findAndStart(const char *name, const char *params = NULL);
				//Finds service with given name and stops it and dependent objects.
				void findAndStop(const char *name);
				//Adds service to base.
				//Note: given service will be released automatically.
				void add(Service *object);
				//Creates empty base.
				ServiceBase(size_t expected_size = 50);
			public:
				//Checks references to instances of the services.
				//Should be called for ensuring of static field initialization.
				static void checkRefs();
				//Returns event, that notifies about finish of starting.
				ttg::structures::Loopback<bool> &onStart()
				{ return on_start; }
				//Returns event, that notifies about start of stopping.
				ttg::structures::Loopback<bool> &onStop()
				{ return on_stop; }
				//Updates all services (which must be updated).
				void update(float step);
				//Starts all services.
				//In case of error throws Error.
				void start();
				//Starts required services.
				//In case of error throws Error.
				//Format: "service1(service1_specific_params) & service2(service2_specific_params)".
				void start(const char *services);
				//Stops all services.
				//In case of error throws Error.
				void stop();
				//Stops selected services.
				//In case of error throws Error.
				void stop(const char *services);
				//Returns object with given name (or NULL).
				inline Service *get(const char *name)
						{ return objects->get(name); }
				//Returns reference to instance (which always exists).
				static ServiceBase *getRef();
				//Returns Logger.
				inline static Logger &_Logger()
				{ return *Logger::getRef(); }
				//Returns SettingKeeper.
				inline static SettingsKeeper &_SKeeper()
				{ return *SettingsKeeper::getRef(); }
				//Returns PublisherBase.
				inline static PublisherBase &_PublisherBase()
				{ return *PublisherBase::getRef(); }
				//Returns DllLoader.
				inline static DllLoader &_DllLoader()
				{ return *DllLoader::getRef(); }
				//Returns reference to HighRes timer.
				inline static Timer &_Timer()
				{ return *Timer::getRef(); }
				//Returns direct reference to DeviceAnalyzer.
				inline static DeviceAnalyzer &_DeviceAnalyzer()
				{ return *DeviceAnalyzer::getRef(); }
				//Returns direct reference to task scheduler.
				inline static TaskScheduler &_TaskScheduler()
				{ return *TaskScheduler::getRef(); }
				//Releases base.
				~ServiceBase();
			friend class Service;
		};
	}
}

#endif
